import Vue from 'vue'
import jwt from 'jwt-simple'
import store from '@/store'
import router from '@/router'
import {SystemRouters, CmsRouters} from '@/router'
import { login, validToken, logout } from '@/api/login'
import { setStore, getStore, removeStore, clearSessionStore } from "@/utils/store";
import { setToken, getToken, removeToken } from "@/utils/auth";

const USER = 'USER', IS_ADMIN = 'IS_ADMIN', ROLES = 'ROLES',
      PAGE_PERMISSIONS = 'PAGE_PERMISSIONS', ACTION_PERMISSIONS = 'ACTION_PERMISSIONS'

const user = {

    state: {
        token: getToken(),
        user: null,
        isAdmin: false,
        roles: [],
        pagePermissions: [],
        actionPermissions: {}
    },

    mutations: {
        SET_TOKEN: (state, token) => {
            state.token = token
            setToken(token)
        },
        SET_USER: (state, data) => {
            state.user = data
            setStore({ name: USER, content: data, type: 'session' })
        },
        SET_IS_ADMIN: (state, data) => {
            state.isAdmin = data
            setStore({ name: IS_ADMIN, content: data, type: 'session' })
        },
        SET_ROLES: (state, data) => {
            state.roles = data
            setStore({ name: ROLES, content: data, type: 'session' })
        },
        SET_PAGE_PERMISSIONS: (state, data) => {
            state.pagePermissions = data
            setStore({ name: PAGE_PERMISSIONS, content: data, type: 'session' })
        },
        SET_ACTION_PERMISSIONS: (state, actionPermissions) => {
            let list = {}
            for(let i=0; i<actionPermissions.length; i++) {
                list[actionPermissions[i]] = true
            }
            state.actionPermissions = list
            setStore({ name: ACTION_PERMISSIONS, content: state.actionPermissions, type: 'session' })
        },
    },

    actions: {

        /**
         * 用户登录
         * @param commit
         * @param state
         * @param data {accout, password}
         * @returns {Promise<any>}
         * @constructor
         */
        Login({ commit, state }, data) {
            return new Promise((resolve, reject) => {
                login(data).then(response => {
                    const token = response.data.data
                    if(token != undefined && response.data.status === 200) {
                        var decodedJwt = jwt.decode(token, process.env.JWT_SECRET, true);

                        //User对象中的ID为long类型（丢失精度），将userId（字符串类型）重新复制给User.id
                        decodedJwt.user['id'] = decodedJwt.userId

                        commit('SET_TOKEN', token)
                        commit('SET_USER', decodedJwt.user)
                        commit('SET_IS_ADMIN', decodedJwt.user.superAdmin)
                        commit('SET_ROLES', decodedJwt.roles)
                        commit('SET_PAGE_PERMISSIONS', decodedJwt.pagePermission)
                        commit('SET_ACTION_PERMISSIONS', decodedJwt.actionPermission)


                        // 生成可访问的路由表
                        let asyncRouter = []
                        let ROUTER_TYPE = getStore({ name: 'ROUTER_TYPE' });
                        if(ROUTER_TYPE === 'CMS') {
                            asyncRouter = CmsRouters
                        } else {
                            asyncRouter = SystemRouters
                        }
                        store.dispatch('GeneratorRouters', asyncRouter).then(() => {
                            router.addRoutes(store.getters.addRouters) // 动态添加可访问路由表
                        })

                    }
                    resolve(response)
                }).catch(() => {
                    reject({status: 500, msg: '登录发生异常，可能服务器未开，请联系管理员'})
                })

            })
        },

        /**
         * 验证Token是否过期
         * @param commit
         * @param state
         * @param data
         * @returns {Promise<any>}
         * @constructor
         */
        ValidToken({ commit, state, dispatch }, data) {
            return new Promise((resolve, reject) => {
                validToken().then(response => {
                    const flag = response.data
                    if(flag) { //Token未过期
                        resolve({status: 200, message: 'Token有效'})
                    } else { //Token已过期
                        dispatch('FedLogOut').then(() => {})
                        resolve({status: 500, message: '登录过期，请重新登录'})
                    }
                }).catch((error) => {
                    reject(error)
                })
            });
        },

        /**
         * 用户刷新了页面，vuex中保存的数据丢失，需重新设置上去
         * @param commit
         * @param state
         * @param dispatch
         * @param data
         * @returns {Promise<any>}
         * @constructor
         */
        SetUserData({ commit, state, dispatch }, data) {
            return new Promise((resolve, reject) => {
                var decodedJwt = jwt.decode(getToken(), process.env.JWT_SECRET, true);

                //User对象中的ID为long类型（丢失精度），将userId（字符串类型）重新复制给User.id
                decodedJwt.user['id'] = decodedJwt.userId
                commit('SET_USER', decodedJwt.user)
                commit('SET_IS_ADMIN', decodedJwt.user.superAdmin)
                commit('SET_ROLES', decodedJwt.roles)
                commit('SET_PAGE_PERMISSIONS', decodedJwt.pagePermission)
                commit('SET_ACTION_PERMISSIONS', decodedJwt.actionPermission)

                resolve()
            });
        },

        // 后端登出
        LogOut({ commit, state, dispatch }) {
            return new Promise((resolve, reject) => {
                logout(state.token).then(() => {
                    dispatch('FedLogOut').then(() => {})
                    resolve()
                }).catch(() => {
                    reject()
                })
            })
        },

        // 前端登出
        FedLogOut({ commit, state }) {
            return new Promise((resolve, reject) => {
                clearSessionStore()
                resolve()
            })
        },

    }
}


export default user
